package cn.com.bluemoon.daps.sync.core.sync.sql.mysql.datatype;

import cn.com.bluemoon.daps.sync.core.sync.sql.mysql.datatype.date.DateTimeDataType;
import cn.com.bluemoon.daps.sync.core.sync.sql.mysql.datatype.date.TimeDataType;
import cn.com.bluemoon.daps.sync.core.sync.sql.mysql.datatype.date.TimestampDataType;
import cn.com.bluemoon.daps.sync.core.sync.sql.mysql.datatype.date.YearDataType;
import cn.com.bluemoon.daps.sync.core.sync.sql.mysql.datatype.number.NumberDataType;
import cn.com.bluemoon.daps.sync.core.sync.sql.mysql.datatype.other.ExpressionStringDataType;
import cn.com.bluemoon.daps.sync.core.sync.sql.mysql.datatype.string.BinaryStringDataType;
import cn.com.bluemoon.daps.sync.core.sync.sql.mysql.datatype.string.StringDataType;
import cn.hutool.core.map.CaseInsensitiveMap;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 字段类型工具类
 * 目前只针对mysql额文档，进行梳理和实现
 *
 * @author Jarod.Kong
 */
@Slf4j
public class DataTypeHelper implements DataType {
    private static Map<String, DataType> dataTypeMap;

    static {
        init();
    }

    private DataTypeHelper() {
    }

    private static synchronized void init() {
        dataTypeMap = new CaseInsensitiveMap<>();
        List<Class<? extends DataType>> clz = Arrays.asList(StringDataType.class,
                ExpressionStringDataType.class, NumberDataType.class, BinaryStringDataType.class,
                YearDataType.class, TimestampDataType.class, TimeDataType.class,
                DateTimeDataType.class);
        clz.forEach(d -> {
            try {
                DataType dt = d.newInstance();
                for (String s : dt.name()) {
                    dataTypeMap.put(s, dt);
                }
            } catch (InstantiationException | IllegalAccessException e) {
                log.error("初始化字段类型处理类失败，", e);
            }
        });
    }

    /**
     * 根据datatype+原有默认值，生成对应的转换后的默认值
     *
     * @param dataTypeStr  字段类型 int/tinyint ...
     * @param defaultValue 源默认值
     * @return 转换后的默认值
     */
    public static Object castDefaultVal(String dataTypeStr, Object defaultValue) {
        DataType dataType = get(dataTypeStr);
        if (dataType == null) {
            return defaultValue;
        }
        // 若为''直接返回
        if (defaultValue.toString().trim().equalsIgnoreCase("''")) {
            return defaultValue;
        }
        Object res = dataType.cast(defaultValue);
        log.debug("解析字段类型为{}的原值：{}，转为：{}", dataTypeStr, defaultValue, res);
        return res;
    }

    /**
     * 根据字段类型获取对象
     * DataType dataType = get("double");
     * assert NumberDataType.class.isAssignableFrom(dataType.getClass());
     * assert dataType.getClass().isAssignableFrom(NumberDataType.class);
     *
     * @param dataTypeStr 字段类型
     * @return 类对象
     */
    public static DataType get(String dataTypeStr) {
        if (dataTypeStr == null) {
            return null;
        }
        DataType dataTypeClz = dataTypeMap.getOrDefault(dataTypeStr, null);
        return dataTypeClz;
    }

    /** 是否为整型类型 */
    public static boolean isIntegerType(String dataTypeStr) {
        if (dataTypeStr == null) return false;
        return NumberDataType.INT_DATA_TYPES.contains(dataTypeStr);
    }
}
